<?php
namespace Home\Controller;
defined('IN_ECTOUCH') or die('Deny Access');
require_once('WxPayDataBase.class.php');
require_once('WxPayResults.class.php');
class WxMoneyPay extends WxPayDataBase
{
  /**
   * app付款方法形成预付单，再次签名
   * @param  [type]  $input_ar [参数数组]
   * @param  integer $timeOut  [description]
   * @return [type]            [description]
   */
  public static function getAppSign($input_ar, $timeOut = 6){
    
    //传参处理
    $out_trade_no=$input_ar['out_trade_no'];
    $body=$input_ar['body']?$input_ar['body']:'暂无';
    $total_fee=$input_ar['total_fee'];
    if($total_fee<0.01)return false;
    
  	$total_fee=$total_fee*100;//单位分

    $create_ip=$_SERVER['REMOTE_ADDR']?$_SERVER['REMOTE_ADDR']:'127.0.0.1';


    //接口地址
    $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";

    $input=array();
    $input['appid']=WxPayDataBase::APPID;//应用ID -必填
    $input['mch_id']=WxPayDataBase::MCHID;//商户号-必填
    $input['device_info']='';//终端设备号(门店号或收银设备ID)，默认请传"WEB"
    $input['nonce_str']=self::getNonceStr();//随机字符串，不长于32位-必填

    $input['notify_url']=get_path_url()."/app_api/notify_url.php";;//接收微信支付异步通知回调地址-必填
    $input['trade_type']='APP';//支付类型
    // $input['limit_pay']='no_credit';//no_credit--指定不能使用信用卡支付

    //变化
    $input['body']=$body;//商品或支付单简要描述-必填
    // $input['detail']='';//商品名称明细列表
    //$input['attach']=''//附加数据
    $input['out_trade_no']=$out_trade_no;//订单号-必填
    // $input['fee_type']='CNY';//默认人民币：CNY
    $input['total_fee']=$total_fee;//订单总金额，单位为分-必填
    $input['spbill_create_ip']=$create_ip;//用户端实际ip-必填
    // $input['time_start']='20091225091010';//订单生成时间
    // $input['time_expire']='20091227092010';//订单失效时间
    // $input['goods_tag']='WXG';//商品标记


    $obj = new self();

    $obj->values=$input;
    // $input['sign']='';//签名-必填
    $obj->SetSign();

    //这里就不做参数验证了
    $xml =$obj->ToXml();



    //传的值
    $value=$obj->values;

    //debug
    // file_put_contents('data.xml', $xml.'\n\n', FILE_APPEND);


    



    $response = self::postXmlCurl($xml, $url, false, $timeOut);
    $result = WxPayResults::Init($response);

     //获取预付单--必须有sign
      if($result['sign']&&$result['return_code']=="SUCCESS")
      {
        if($result['result_code']=="SUCCESS")
        {
          // $trade_type=$result['trade_type'];//交易类型
          //构造APP端调起支付的参数列表
          $app_pay['appid']=WxPayDataBase::APPID;
          $app_pay['partnerid']=WxPayDataBase::MCHID;//商户号-必填
          $app_pay['prepayid']=$result['prepay_id'];//微信生成的预支付回话标识-有效期为2小时
          $app_pay['package']="Sign=WXPay";//扩展字段
          $app_pay['noncestr']=self::getNonceStr();//随机字符串，不长于32位-必填
          // $startTimeStamp = substr((self::getMillisecond()),-10);
          $app_pay['timestamp']=time();//部分系统取到的值为毫秒级，需要转换成秒(10位数字)
          

          $obj->values=$app_pay;
          $obj->SetSign();

          return $obj->values;
        }

      }
      else //报错
      {
        $result['prepayid']='';
      }



    // self::reportCostTime($url, $startTimeStamp, $result);//上报请求花费时间

    //
    
    return $result;
  }

    /**
   * 获取付款返回结果
   * @param  [type]  $output [参数数组]
   */
  public static function getNotifyFormXml($response){

       $result = WxPayResults::Init($response);
       //签名错误-- 非法操作
       if(empty($result['sign']))
       {
          $result=array(); 
          $result['return_code']="FAIL";
          $result['return_msg']="签名错误,非法操作";
       }

       return $result;

  }
      /**
   * 获取付款返回结果
   * @param  [type]  $output [参数数组]
   */
  public static function getNotifyFormArray($response){

       $result = WxPayResults::InitArray($response);
       //签名错误-- 非法操作
       if(empty($result['sign']))
       {
          $result=array(); 
          $result['return_code']="FAIL";
          $result['return_msg']="签名错误,非法操作";
       }

       return $result;

  }

 /**
   * app付款  查询订单
   * @param  [type]  $input_ar [参数数组]
   * @param  integer $timeOut  [description]
   * @return [type]            [description]
   */
  public static function checkAppOrder($input_ar, $timeOut = 6){
    
    //传参处理
    $out_trade_no=$input_ar['out_trade_no'];
    


    //接口地址
    $url = "https://api.mch.weixin.qq.com/pay/orderquery";

    $input=array();
    $input['appid']=WxPayDataBase::APPID;//应用ID -必填
    $input['mch_id']=WxPayDataBase::MCHID;//商户号-必填
   
    $input['nonce_str']=self::getNonceStr();//随机字符串，不长于32位-必填


    //变化
    $input['out_trade_no']=$out_trade_no;//订单号-必填
    // $input['transaction_id']='';//微信的订单号-二选一


    $obj = new self();

    $obj->values=$input;
    // $input['sign']='';//签名-必填
    $obj->SetSign();

    //这里就不做参数验证了
    $xml =$obj->ToXml();



    //传的值
    // $value=$obj->values;

    //debug
    // file_put_contents('data.xml', $xml.'\n\n', FILE_APPEND);


    



    $response = self::postXmlCurl($xml, $url, false, $timeOut);
    $result = WxPayResults::Init($response);
    
    return $result;
  }
 /**
   * 以post方式提交xml到对应的接口url
   * Enter description here ...
   * @param string $xml  需要post的xml数据
   * @param string $url  url
   * @param bool $useCert 是否需要证书，默认不需要
   * @param int $second   url执行超时时间，默认30s
   * @throws WxPayException
   */
  private static function postXmlCurl($xml, $url, $useCert = false, $second = 30)
  {   
    //初始化curl        
    $ch = curl_init();
    //设置超时
    curl_setopt($ch, CURLOPT_TIMEOUT, $second);
    
    
    //如果有配置代理这里就设置代理
    if(WxPayDataBase::CURL_PROXY_HOST != "0.0.0.0" 
      && WxPayDataBase::CURL_PROXY_PORT != 0){
      curl_setopt($ch,CURLOPT_PROXY, WxPayDataBase::CURL_PROXY_HOST);
      curl_setopt($ch,CURLOPT_PROXYPORT, WxPayDataBase::CURL_PROXY_PORT);
    }
    curl_setopt($ch,CURLOPT_URL, $url);
    curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
    curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);

 
    //设置header
    curl_setopt($ch, CURLOPT_HEADER, FALSE);
    //要求结果为字符串且输出到屏幕上
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  
    if($useCert == true){
      //设置证书
      //使用证书：cert 与 key 分别属于两个.pem文件

      $PATH=dirname(dirname(dirname(dirname(dirname(dirname(dirname(dirname(dirname(__FILE__)))))))))."/data_pem"; 
      $SSLCERT_PATH =  $PATH.'/apiclient_cert.pem';
      $SSLKEY_PATH =   $PATH.'/apiclient_key.pem';
  
      curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
      curl_setopt($ch,CURLOPT_SSLCERT, $SSLCERT_PATH);
      
      curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
      curl_setopt($ch,CURLOPT_SSLKEY,  $SSLKEY_PATH);

      
    }
    //post提交方式
    curl_setopt($ch, CURLOPT_POST, TRUE);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);

    //运行curl
    $data = curl_exec($ch);

    //debug 返回结果写入文件
    // file_put_contents('data.xml', $data.'\n\n',FILE_APPEND);

    //返回结果
    if($data){
      curl_close($ch);
      return $data;
    } else { 
      $error = curl_errno($ch);
      curl_close($ch);
      // throw new WxPayException("curl出错，错误码:$error");
    }
  }
  private static function getMillisecond()
  {
    //获取毫秒的时间戳
    $time = explode ( " ", microtime () );
    $time = $time[1] . ($time[0] * 1000);
    $time2 = explode( ".", $time );
    $time = $time2[0];
    return $time;
  }

    /**
   * 生成 nonce_str 随机串
   * @param  integer $length [description]
   * @return [type]          [description]
   */
  public static function getNonceStr($length = 32) 
  {
    $chars = "abcdefghijklmnopqrstuvwxyz0123456789";  
    $str ="";
    for ( $i = 0; $i < $length; $i++ )  {  
      $str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);  
    } 
    return $str;
  }

}

